#include "encrypt.h"

#if 0
/***  RSA  ***/
#include "global.h"
#include "rsa_incl.h"
#include "rsaref.h"
#include "rsa.h"
#include "md5.h"
#include "des.h"
#include "nn.h"
#include "ied.h"
#define Encrypt_RSA  1
#else
#include "bignum.h"
#include "rsa.h"
#define Encrypt_RSA  0
#endif
#include "rsa_keys.h"

#define  debug_log     0
#ifndef debug_log
#define  debug_log     1
#endif
//#undef   debug_log
#include <stdio.h>
#include <string.h>

//#ifdef debug_log
#if debug_log
#define pr_debug(fmt, ...) printf(fmt, ##__VA_ARGS__); fflush(stdout);
#else
#define pr_debug(fmt, ...) ;
#endif

#if 0
typedef struct {
    unsigned short int bits;                     /* length in bits of modulus */
    unsigned char modulus[MAX_RSA_MODULUS_LEN];  /* modulus */
    unsigned char exponent[MAX_RSA_MODULUS_LEN]; /* public exponent */
} R_RSA_PUBLIC_KEY;
typedef struct {
    unsigned short int bits;                     /* length in bits of modulus */
    unsigned char modulus[MAX_RSA_MODULUS_LEN];  /* modulus */
    unsigned char publicExponent[MAX_RSA_MODULUS_LEN];     /* public exponent */
    unsigned char exponent[MAX_RSA_MODULUS_LEN]; /* private exponent */
    unsigned char prime[2][MAX_RSA_PRIME_LEN];   /* prime factors */
    unsigned char primeExponent[2][MAX_RSA_PRIME_LEN];     /* exponents for CRT */
    unsigned char coefficient[MAX_RSA_PRIME_LEN];          /* CRT coefficient */
} R_RSA_PRIVATE_KEY;
#endif

void print_bn_arr(char *TAG, uint8_t *array, int len)
{
    int i = 0;

    printf("%s", TAG);
    while(array[i] == 0) {
        i++;
    }
    for(; i<len; i++) {
        printf("0x%02X,", array[i]);
    }
    printf("\n");
}

#if  Encrypt_RSA
/* RSA public key */
static R_RSA_PUBLIC_KEY rsa_public_key;
/* RSA private key */
static R_RSA_PRIVATE_KEY rsa_private_key;
void print_pk(R_RSA_PUBLIC_KEY *pk)
{
    printf("PK[%d]:\n", pk->bits);
    print_bn_arr("  modulus: ", pk->modulus, MAX_RSA_MODULUS_LEN);
    print_bn_arr("  exponent: ", pk->exponent, MAX_RSA_MODULUS_LEN);
}

void print_sk(R_RSA_PRIVATE_KEY *sk)
{
    printf("SK[%d]:\n", sk->bits);
    print_bn_arr("  modulus: ", sk->modulus, MAX_RSA_MODULUS_LEN);
    print_bn_arr("  public_exponet: ", sk->publicExponent, MAX_RSA_MODULUS_LEN);
    print_bn_arr("  exponent: ", sk->exponent, MAX_RSA_MODULUS_LEN);
    print_bn_arr("  prime1: ", sk->prime[0], MAX_RSA_PRIME_LEN);
    print_bn_arr("  prime2: ", sk->prime[1], MAX_RSA_PRIME_LEN);
    print_bn_arr("  primeExponent1: ", sk->primeExponent[0], MAX_RSA_PRIME_LEN);
    print_bn_arr("  primeExponent2: ", sk->primeExponent[1], MAX_RSA_PRIME_LEN);
    print_bn_arr("  coefficient: ", sk->coefficient, MAX_RSA_PRIME_LEN);
}
void rsa_int(void)
{
    memset(&rsa_public_key, 0, sizeof (rsa_public_key));
    memset(&rsa_private_key, 0, sizeof (rsa_private_key));
    rsa_public_key.bits = KEY_M_BITS;
    memcpy(&rsa_public_key.modulus[MAX_RSA_MODULUS_LEN-sizeof(public_modulus)], public_modulus, sizeof(public_modulus));
    memcpy(&rsa_public_key.exponent[MAX_RSA_MODULUS_LEN-sizeof(public_exponent)], public_exponent, sizeof(public_exponent));

    rsa_private_key.bits = KEY_M_BITS;
    memcpy(&rsa_private_key.modulus[MAX_RSA_MODULUS_LEN-sizeof(private_modulus)], private_modulus, sizeof(private_modulus));
    memcpy(&rsa_private_key.publicExponent[MAX_RSA_MODULUS_LEN-sizeof(private_public_exponet)], private_public_exponet, sizeof(private_public_exponet));
    memcpy(&rsa_private_key.exponent[MAX_RSA_MODULUS_LEN-sizeof(private_exponent)], private_exponent, sizeof(private_exponent));
    memcpy(&rsa_private_key.prime[0][MAX_RSA_PRIME_LEN-sizeof(key_p1)], key_p1, sizeof(key_p1));
    memcpy(&rsa_private_key.prime[1][MAX_RSA_PRIME_LEN-sizeof(key_p2)], key_p2, sizeof(key_p2));
    memcpy(&rsa_private_key.primeExponent[0][MAX_RSA_PRIME_LEN-sizeof(key_e1)], key_e1, sizeof(key_e1));
    memcpy(&rsa_private_key.primeExponent[1][MAX_RSA_PRIME_LEN-sizeof(key_e2)], key_e2, sizeof(key_e2));
    memcpy(&rsa_private_key.coefficient[MAX_RSA_PRIME_LEN-sizeof(key_c)], key_c, sizeof(key_c));
#if 0
    //rsa_generate_keys(&rsa_public_key, &rsa_private_key, 1024);
    print_pk(&rsa_public_key);
    printf("\n");
    print_sk(&rsa_private_key);
#endif
}

int rsa_encrypt(void *output, const int outputLen, void *input, const int inputLen)
{
#if 0 // 短报文加密
    int status = 0;
    unsigned int dlen=(unsigned int)outputLen;
    pr_debug("rsa_encrypt RSA data_len: %d inputLen:%d\n", dlen, inputLen);
    status = RSAPrivateEncrypt(output, &dlen, input, (unsigned int)inputLen, &rsa_private_key);
    //status = RSAPrivateEncrypt(dat,&dlen,md5,sizeof(md5), &rsa_private_key);
    pr_debug("rsa_encrypt RSA data_len: %d status:0x%02X \n", dlen, status);
    if(ID_OK!=status) return -1;
    return (int)dlen;
#else // 长报文分包加密
    int status = 0;
    int ilen=0;
    int olen=0;
    unsigned int _size=0;
    unsigned int dlen=(unsigned int)outputLen;
    pr_debug("rsa_encrypt RSA data_len: %d inputLen:%d\n", dlen, inputLen);
    olen=0;
    for(ilen=0; ilen<inputLen; ilen += 117) // 拆分成 117字节包进行加密
    {
        if((ilen+117)<inputLen) _size = 117;
        else _size = inputLen-ilen;
        status = RSAPrivateEncrypt(((uint8_t*)output+olen), &dlen, ((uint8_t*)input+ilen), _size, &rsa_private_key);
        pr_debug("rsa_encrypt[%d] RSA data_len: %d status:0x%02X \n", ilen, dlen, status);
        if(ID_OK!=status) return -1;
        olen += dlen;
    }
    return olen;
#endif
}

int rsa_decrypt(void *output, const int outputLen, void *input, const int inputLen)
{
#if 0 // 短报文解密
    int status = 0;
    unsigned int dlen=(unsigned int)outputLen;
    pr_debug("rsa_decrypt RSA data_len: %d inputLen:%d\n", dlen, inputLen);
    status = RSAPublicDecrypt(output, &dlen, input, (unsigned int)inputLen, &rsa_public_key);
    //status = RSAPublicDecrypt(dat,&dlen,dat,dlen,&rsa_public_key);
    pr_debug("rsa_decrypt RSA data_len: %d status:0x%02X \n", dlen, status);
    if(ID_OK!=status) return -1;
    return (int)dlen;
#else // 长报文分包解密
    int status = 0;
    int ilen=0;
    int olen=0;
    unsigned int _size=0;
    unsigned int dlen=(unsigned int)outputLen;
    pr_debug("rsa_decrypt RSA data_len: %d inputLen:%d\n", dlen, inputLen);
    olen=0;
    for(ilen=0; ilen<inputLen; ilen += 128) // 拆分成 128 字节包进行解密
    {
        if((ilen+128)<inputLen) _size = 128;
        else _size = inputLen-ilen;
        status = RSAPublicDecrypt(((uint8_t*)output+olen), &dlen, ((uint8_t*)input+ilen), _size, &rsa_public_key);
        pr_debug("rsa_decrypt[%d] RSA data_len: %d status:0x%02X \n", ilen, dlen, status);
        if(ID_OK!=status) return -1;
        olen += dlen;
    }
    return olen;
#endif
}
#else
/* RSA public key */
rsa_pk_t rsa_public_key;
/* RSA private key */
rsa_sk_t rsa_private_key;

void print_pk(rsa_pk_t *pk)
{
    printf("PK[%d]:\n", pk->bits);
    print_bn_arr("  modulus: ", pk->modulus, RSA_MAX_MODULUS_LEN);
    print_bn_arr("  exponent: ", pk->exponent, RSA_MAX_MODULUS_LEN);
}

void print_sk(rsa_sk_t *sk)
{
    printf("SK[%d]:\n", sk->bits);
    print_bn_arr("  modulus: ", sk->modulus, RSA_MAX_MODULUS_LEN);
    print_bn_arr("  public_exponet: ", sk->public_exponet, RSA_MAX_MODULUS_LEN);
    print_bn_arr("  exponent: ", sk->exponent, RSA_MAX_MODULUS_LEN);
    print_bn_arr("  prime1: ", sk->prime1, RSA_MAX_PRIME_LEN);
    print_bn_arr("  prime2: ", sk->prime2, RSA_MAX_PRIME_LEN);
    print_bn_arr("  primeExponent1: ", sk->prime_exponent1, RSA_MAX_PRIME_LEN);
    print_bn_arr("  primeExponent2: ", sk->prime_exponent2, RSA_MAX_PRIME_LEN);
    print_bn_arr("  coefficient: ", sk->coefficient, RSA_MAX_PRIME_LEN);
}
void rsa_int(void)
{
    memset(&rsa_public_key, 0, sizeof (rsa_public_key));
    memset(&rsa_private_key, 0, sizeof (rsa_private_key));
    rsa_public_key.bits = KEY_M_BITS;
    memcpy(&rsa_public_key.modulus[RSA_MAX_MODULUS_LEN-sizeof(public_modulus)], public_modulus, sizeof(public_modulus));
    memcpy(&rsa_public_key.exponent[RSA_MAX_MODULUS_LEN-sizeof(public_exponent)], public_exponent, sizeof(public_exponent));

    rsa_private_key.bits = KEY_M_BITS;
    memcpy(&rsa_private_key.modulus[RSA_MAX_MODULUS_LEN-sizeof(private_modulus)], private_modulus, sizeof(private_modulus));
    memcpy(&rsa_private_key.public_exponet[RSA_MAX_MODULUS_LEN-sizeof(private_public_exponet)], private_public_exponet, sizeof(private_public_exponet));
    memcpy(&rsa_private_key.exponent[RSA_MAX_MODULUS_LEN-sizeof(private_exponent)], private_exponent, sizeof(private_exponent));
    memcpy(&rsa_private_key.prime1[RSA_MAX_PRIME_LEN-sizeof(key_p1)], key_p1, sizeof(key_p1));
    memcpy(&rsa_private_key.prime2[RSA_MAX_PRIME_LEN-sizeof(key_p2)], key_p2, sizeof(key_p2));
    memcpy(&rsa_private_key.prime_exponent1[RSA_MAX_PRIME_LEN-sizeof(key_e1)], key_e1, sizeof(key_e1));
    memcpy(&rsa_private_key.prime_exponent2[RSA_MAX_PRIME_LEN-sizeof(key_e2)], key_e2, sizeof(key_e2));
    memcpy(&rsa_private_key.coefficient[RSA_MAX_PRIME_LEN-sizeof(key_c)], key_c, sizeof(key_c));
#if 0
    //rsa_generate_keys(&rsa_public_key, &rsa_private_key, 1024);
    print_pk(&rsa_public_key);
    printf("\n");
    print_sk(&rsa_private_key);
#endif
}


int rsa_encrypt(void *output, const int outputLen, void *input, const int inputLen)
{
    // 长报文分包加密
    int status = 0;
    int ilen=0;
    int olen=0;
    unsigned int _size=0;
    uint32_t dlen=(uint32_t)outputLen;
    //rsa_generate_keys(&rsa_public_key, &rsa_private_key, 1024);
    pr_debug("rsa_encrypt RSA data_len: %d inputLen:%d\n", dlen, inputLen);
    olen=0;
    for(ilen=0; ilen<inputLen; ilen += 117) // 拆分成 117字节包进行加密
    {
        if((ilen+117)<inputLen) _size = 117;
        else _size = inputLen-ilen;
        status = rsa_private_encrypt(((uint8_t*)output+olen), &dlen, ((uint8_t*)input+ilen), _size, &rsa_private_key);
        pr_debug("rsa_encrypt[%d] RSA data_len: %d status:0x%02X \n", ilen, dlen, status);
        if(0!=status) return -1;
        olen += dlen;
    }
    return olen;
}

int rsa_decrypt(void *output, const int outputLen, const void *const input, const int inputLen)
{
    // 长报文分包解密
    int status = 0;
    int ilen=0;
    int olen=0;
    unsigned int _size=0;
    uint32_t dlen=(uint32_t)outputLen;
    pr_debug("rsa_decrypt RSA data_len: %d inputLen:%d\n", dlen, inputLen);
    olen=0;
    for(ilen=0; ilen<inputLen; ilen += 128) // 拆分成 128 字节包进行解密
    {
        if((ilen+128)<inputLen) _size = 128;
        else _size = inputLen-ilen;
        status = rsa_public_decrypt(((uint8_t*)output+olen), &dlen, ((uint8_t*)input+ilen), _size, &rsa_public_key);
        pr_debug("rsa_decrypt[%d] RSA data_len: %d status:0x%02X \n", ilen, dlen, status);
        if(0!=status) return -1;
        olen += dlen;
    }
    return olen;
}
#endif






